#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <unistd.h>
#include "modbus_device_socket.h"


uint8_t test_data[2048];
uint16_t test_data_size;
int32_t test_status;
int listen_fd, accept_fd;


int count = 0;

int main(int argc, char **argv)
{
#if 1
  
  struct sockaddr_in server_addr;
  int length = 0;
  char buffer[1024];
  int ret;
  int opt = 1; 

  MODBUS_Device_Register(&modbus_device_socket);

RESTART:
    count = 0;

    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd < 0)
    {
      printf("socket error:%s\r\n", strerror(errno));
      exit(1);
    }
    else
    {
      printf("socket ok\r\n");
    }

    ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if (ret < 0)  
    {  
      printf("setsockopt error:%s\r\n", strerror(errno));
      exit(1);  
    }
    else
    {
      printf("setsockopt ok\r\n");
    }

    bzero(&server_addr, sizeof(struct sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8000);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    ret = bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
    {
      printf("bind error:%s\r\n", strerror(errno));
      exit(1);
    }
    else
    {
      printf("bind ok\r\n");
    }

    ret = listen(listen_fd, 1);
    if (ret < 0)
    {
      printf("listen error:%s\r\n", strerror(errno));
      exit(1);
    }
    else
    {
      printf("listen ok\r\n");
    }

    while (1)
    {
    
      accept_fd = accept(listen_fd, NULL, NULL);
      if ((accept_fd < 0) && (errno == EINTR))
      {
        close(accept_fd);
        printf("accept error\r\n");
      }
      else
      {
        printf("accept ok\r\n");       
      }

      close(listen_fd);
      printf("listen_fd close\r\n");

      while (1)
      {
        length = recv(accept_fd, buffer, 1024, 0);
        if (length >= 1)
        {
          test_status = MODBUS_TRANSFER_STATUS_END;
          test_data_size = length;
          memcpy(test_data, buffer, test_data_size);

          MODBUS_Device_Data_Processing(&modbus_device_socket, MODBUS_TCP);

          test_data_size = 0;
          test_status = MODBUS_TRANSFER_STATUS_IDLE;

          count++;
          printf("write ok:%d\r\n", count);
        }
        else
        {
          close(accept_fd);
          printf("accept_fd close\r\n");
          break;
        }
      }
      goto RESTART;
    }
 

#else
  int listen_fd, accept_fd;
  struct sockaddr_in client_addr;
  int length = 0;
  char buffer[1024] ={0};
  int ret;

  listen_fd = socket(AF_INET,SOCK_STREAM,0);

  if (listen_fd < 0)
  {
    printf("socket error:%s\r\n", strerror(errno));
    exit(1);
  }

  bzero(&client_addr, sizeof(struct sockaddr_in));
  client_addr.sin_family = AF_INET;
  client_addr.sin_port = htons(8000);
  client_addr.sin_addr.s_addr = htonl(INADDR_ANY);

  ret = bind(listen_fd, (struct sockaddr *)&client_addr, sizeof(client_addr));
  if (ret < 0)
  {
    printf("bind error:%s\r\n", strerror(errno));
    exit(1);
  }

  ret = listen(listen_fd, 1);
  if (ret < 0)
  {
    printf("listen error:%s\r\n", strerror(errno));
    exit(1);
  }

  while (1)
  {
    accept_fd = accept(listen_fd, NULL, NULL);
    if ((accept_fd < 0) && (errno == EINTR))
    {
      continue;
    }
    

    if (fork() == 0)
    {
      close(listen_fd);
      length = read(accept_fd, buffer, 1024);
      if (length > 1)
      {
        buffer[length - 1] = '\0';
        printf("get string:%s\r\n", buffer); 
      }
      close(accept_fd);
      exit(0);
    }
    close(accept_fd);
  }
#endif
}


